﻿/* *
 * =============================================================================
 * File Name:               ConstantHigh.cs
 * Programmer:              Ken Watts
 * Creation Date:           8/3/2008
 * =============================================================================
 * Description:             Class that represents a logical 1 value.
 * =============================================================================
 * Modification Date:       8/3/2008 - Initial Revision
 * =============================================================================
 * */

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DigitalLogicSimulator
{
    public class ConstantHigh : Device
    {
        // Constants
        private const double k_initial_top = 120;
        private const double k_initial_left = 20;
        // Perimeter points
        private const double k_p1_x = 20;
        private const double k_p1_y = 15;
        private const double k_p2_x = 0;
        private const double k_p2_y = 15;
        private const double k_p3_x = 0;
        private const double k_p3_y = 0;
        private const double k_p4_x = 20;
        private const double k_p4_y = 0;
        private const double k_out_p1_x = 20;
        private const double k_out_p1_y = 8;
        private const double k_out_p2_x = 30;
        private const double k_out_p2_y = 8;
        private const double k_plus_p1_x = 5;
        private const double k_plus_p1_y = 4;
        private const double k_plus_p2_x = 5;
        private const double k_plus_p2_y = 10;
        private const double k_plus_p3_x = 2;
        private const double k_plus_p3_y = 7;
        private const double k_plus_p4_x = 8;
        private const double k_plus_p4_y = 7;
        private const double k_v_p1_x = 9;
        private const double k_v_p1_y = 2;
        private const double k_v_p2_x = 13;
        private const double k_v_p2_y = 12;
        private const double k_v_p3_x = 17;
        private const double k_v_p3_y = 2;

        public ConstantHigh()
        {
            // Ensure output state is always high
            outputState = true;
            // Do not highlight
            highlightColor = backgroundColor;
            highlightBrush = new SolidColorBrush(highlightColor);
        }

        protected override void ReplaceInstance(Panel parentPanel)
        {
            parentPanel.Children.Add(new ConstantHigh());
        }

        protected override void Draw()
        {
            pathGeometry = new PathGeometry();
            pathGeometry.FillRule = FillRule.Nonzero;
            PathFigure pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_p1_x, k_p1_y);
            pathFigure.IsClosed = true;
            pathGeometry.Figures = new PathFigureCollection();
            pathGeometry.Figures.Add(pathFigure);
            pathFigure.Segments = new PathSegmentCollection();

            // Draw outline 
            LineSegment ls = new LineSegment();
            ls.Point = new Point(k_p2_x, k_p2_y);
            pathFigure.Segments.Add(ls);
            ls = new LineSegment();
            ls.Point = new Point(k_p3_x, k_p3_y);
            pathFigure.Segments.Add(ls);
            ls = new LineSegment();
            ls.Point = new Point(k_p4_x, k_p4_y);
            pathFigure.Segments.Add(ls);

            // Add output
            pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_out_p1_x, k_out_p1_y);
            pathFigure.Segments = new PathSegmentCollection();
            ls = new LineSegment();
            ls.Point = new Point(k_out_p2_x, k_out_p2_y);
            pathFigure.Segments.Add(ls);
            pathGeometry.Figures.Add(pathFigure);

            // Add "+Vcc"
            pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_plus_p1_x, k_plus_p1_y);
            pathFigure.Segments = new PathSegmentCollection();
            ls = new LineSegment();
            ls.Point = new Point(k_plus_p2_x, k_plus_p2_y);
            pathFigure.Segments.Add(ls);
            pathGeometry.Figures.Add(pathFigure);
            pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_plus_p3_x, k_plus_p3_y);
            pathFigure.Segments = new PathSegmentCollection();
            ls = new LineSegment();
            ls.Point = new Point(k_plus_p4_x, k_plus_p4_y);
            pathFigure.Segments.Add(ls);
            pathGeometry.Figures.Add(pathFigure);
            pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_v_p1_x, k_v_p1_y);
            pathFigure.Segments = new PathSegmentCollection();
            ls = new LineSegment();
            ls.Point = new Point(k_v_p2_x, k_v_p2_y);
            pathFigure.Segments.Add(ls);
            pathGeometry.Figures.Add(pathFigure);
            pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(k_v_p2_x, k_v_p2_y);
            pathFigure.Segments = new PathSegmentCollection();
            ls = new LineSegment();
            ls.Point = new Point(k_v_p3_x, k_v_p3_y);
            pathFigure.Segments.Add(ls);
            pathGeometry.Figures.Add(pathFigure);

            // Setup the path
            path = new Path();
            path.Stretch = Stretch.Fill;
            path.StrokeLineJoin = PenLineJoin.Round;
            path.Stroke = new SolidColorBrush(strokeColor);
            path.Fill = new SolidColorBrush(backgroundColor);
            path.StrokeThickness = k_dbl_stroke_thickness;
            path.Data = pathGeometry;
            path.MouseLeftButtonDown += new MouseButtonEventHandler(CustomMouseLeftButtonDown);
            path.MouseLeftButtonUp += new MouseButtonEventHandler(CustomMouseLeftButtonUp);
            path.MouseMove += new MouseEventHandler(CustomMouseMove);
            path.MouseEnter += new MouseEventHandler(CustomMouseEnter);
            path.MouseLeave += new MouseEventHandler(CustomMouseLeave);

            Children.Add(path);
            
            // Setup output points
            outputLeft.X = k_out_p1_x;
            outputLeft.Y = k_out_p1_y;
            outputRight.X = k_out_p2_x;
            outputRight.Y = k_out_p2_y;

            // Setup rubberband output line
            outputLine = new Line();
            outputLine.Stroke = new SolidColorBrush(rubberbandColor);
            outputLine.StrokeThickness = k_dbl_stroke_thickness;
            outputLine.Visibility = System.Windows.Visibility.Collapsed;

            Children.Add(outputLine);            

            // Set the initial position
            path.SetValue(Canvas.LeftProperty, k_initial_left);
            path.SetValue(Canvas.TopProperty, k_initial_top);
            canvLeft = k_initial_left;
            canvTop = k_initial_top;

        }

        protected override int Connect(Device logicDevice, Point clickedPoint)
        {
            // Can't connect...
            return k_int_not_connected;
        }

        protected override Point GetInputLocation(int inputNumber)
        {
            // Has no inputs
            Point p = new Point();
            return p;
        }

        // Sets the state of the specified input to the given value
        public override void SetInputState(int inputNumber, bool state)
        {
            // Has no inputs
        }

    }
}
